﻿using System;
using System.Collections.Generic;
using System.Linq;
using Netfraction.Common;

namespace Netfraction.Network.Protocol.BASE.Handler
{
    public class HandlerGPA : ProtocolMessageActionHandler
    {
        public HandlerGPA()
            : base()
        {
            mSupportedConnectionStates = new List<RemoteMachine.ConnectionState>();
        }

        #region ProtocolMessageActionHandler Members

        public override string ProtocolActionCode
        {
            get { return "GPA"; }
        }

        public override bool HandleProtocolMessage(Netfraction.RemoteMachine.Node node, ProtocolMessage message, IEnumerable<ProtocolFeature> extenders)
        {
            if (node is RemoteMachine.Hub)
            {
                Console.WriteLine("in GPA handler");
                if (message.Parameters.Count == 1)
                {
                    //message.GETParameterOptions = DecodeParameters(message.GETParameterOptions);
                    //(node as RemoteMachine.Hub).SessionId = message.GETParameterOptions[0].ParameterValue;
                    //Console.WriteLine("Source SID: {0}", message.SessionId);
                    string salt = message.Parameters[0].ParameterValue;
                    if (salt.Length > 0) // ADC 1.0 requires at least 24 random bytes (base32 encoded)
                    {
                        byte[] saltBytes = new byte[salt.Length * 5 / 8];
                        saltBytes = Base32.Decode(salt);

                        LocalMachine.Client client = LocalMachine.Client.GetInstance();

                        byte[] passwordBytes = System.Text.Encoding.UTF8.GetBytes(client.Identity.Password);

                        byte[] seed = new byte[passwordBytes.Length + saltBytes.Length];
                        for (int i = 0; i < passwordBytes.Length; i++)
                        {
                            seed[i] = passwordBytes[i];
                        }
                        for (int i = 0; i < saltBytes.Length; i++)
                        {
                            seed[i + passwordBytes.Length] = saltBytes[i];
                        }

                        node.SessionHashAlgorithm.Initialize();

                        byte[] hash = node.SessionHashAlgorithm.ComputeHash(seed);

                        string passHash = Base32.Encode(hash);

                        ProtocolMessageFactory factory = new Factory.FactoryPAS();

                        Dictionary<int, object> factoryParams = new Dictionary<int, object>();
                        factoryParams.Add((int)Factory.FactoryPAS.ParameterEnum.Data, passHash);
                        // Send Client Information to Hub
                        (node as RemoteMachine.Hub).Connection.Send(factory.Create(ProtocolMessage.MessageTypeEnum.Hub, factoryParams).ToString());
                    }
                    /*
                    boost::scoped_array<uint8_t> mBuffer(new uint8_t[saltBytes]);
		            Encoder::fromBase32(salt.c_str(), &mBuffer[0], saltBytes);
		            TigerHash th;
		            if(oldPassword) {
			            CID cid = getMyIdentity().getUser()->getCID();
			            th.update(cid.array(), CID::SIZE);
		            }
		            th.update(pwd.array(), pwd.length());
		            th.update(&mBuffer[0], saltBytes);
		            send(AdcCommand(AdcCommand::CMD_PAS, AdcCommand::TYPE_HUB).addParam(Encoder::toBase32(th.finalize(), TigerHash::BYTES)));
		            salt.clear();*/
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        #endregion
    }
}
